package com.pic.mgt.action;

import java.util.List;

import com.pic.mgt.controller.UnitController;
import com.pic.mgt.executer.UnitDispatcher;
import com.pic.mgt.log.IgxLog;
import com.pic.mgt.monitor.UnitMonitor;
import com.pic.mgt.scheduler.Scheduler;
import com.pic.mgt.telnetd.CommandPerformer;
import com.pic.mgt.telnetd.ShellCommandHandler;
import com.pic.mgt.telnetd.TelnetD;
import com.pic.mgt.utils.RunTimeSystemUtils;

public class ShutdownSystemActionImpl implements ShutdownSystemAction {
	private UnitMonitor businessUnitMonitor;
	private UnitMonitor messageUnitMonitor;
	private UnitController businessUnitController;
	private UnitController messageUnitController;
	private UnitDispatcher businessUnitDispatcher;
	private UnitDispatcher messageUnitDispatcher;
	private Scheduler scheduler;
	private TelnetD telnetD;
	private ShellCommandHandler shellCommandHandler;
	
	@Override
	public void shutdownSystem() {
		
		// ********************** Log **********************
		IgxLog.messageLog.info(this, "Shuting system down.");
		// ********************** Log **********************

		// ---------- 系統關閉前的前置處理 ------------------
		
		// 1. 停止 Console Shell Command 服務 (亦即關閉 Telnet Service)
		this.telnetD.stopTelnetD();
		
		// 2. 若有 Console 指令動作正在執行中，則等待到執行完
		waitingForAllCommandPerformingCompleted();
		
		// 3. 停止 業務/訊息 的監控處理佇列
		this.businessUnitMonitor.stopUnitMonitor();
		this.messageUnitMonitor.stopUnitMonitor();
		
		// 4. 停止 業務/訊息 的控制處理佇列
		this.businessUnitController.destory();
		this.messageUnitController.destory();
		
		// 5. 停止 業務/訊息 的分派處理佇列
		this.businessUnitDispatcher.destory();
		this.messageUnitDispatcher.destory();
		
		// 6. 關閉 Schedule 排程
		this.scheduler.shutdownScheduler();
		
		// ********************** Log **********************
		IgxLog.messageLog.info(this, "Shutdown system completed.");
		// ********************** Log **********************
		
		
		// ---------- 結束系統 !!! ------------------
	}
	
	private void waitingForAllCommandPerformingCompleted() {
		List<CommandPerformer> commandPerformerList =
					this.shellCommandHandler.getCommandPerformerList();
		
		for (CommandPerformer commandPerformer : commandPerformerList) {
			while(commandPerformer.isCurrentPerforming()) {
				RunTimeSystemUtils.threadSleep(500);
			}
		}
	}
	
	// --- getter and setter ---
	
	public void setBusinessUnitMonitor(UnitMonitor businessUnitMonitor) {
		this.businessUnitMonitor = businessUnitMonitor;
	}

	public void setMessageUnitMonitor(UnitMonitor messageUnitMonitor) {
		this.messageUnitMonitor = messageUnitMonitor;
	}

	public void setScheduler(Scheduler scheduler) {
		this.scheduler = scheduler;
	}

	public void setTelnetD(TelnetD telnetD) {
		this.telnetD = telnetD;
	}

	public void setShellCommandHandler(ShellCommandHandler shellCommandHandler) {
		this.shellCommandHandler = shellCommandHandler;
	}

	public void setBusinessUnitDispatcher(UnitDispatcher businessUnitDispatcher) {
		this.businessUnitDispatcher = businessUnitDispatcher;
	}

	public void setMessageUnitDispatcher(UnitDispatcher messageUnitDispatcher) {
		this.messageUnitDispatcher = messageUnitDispatcher;
	}

	public void setBusinessUnitController(UnitController businessUnitController) {
		this.businessUnitController = businessUnitController;
	}

	public void setMessageUnitController(UnitController messageUnitController) {
		this.messageUnitController = messageUnitController;
	}
}
